// ------------------------------------
// Utils
// ------------------------------------
import _ from 'lodash'
import { httpServices } from 'http-services'
import config from 'config'
import Flag from 'config/flag'
import fetchMock from 'fetch-mock'
import { postData } from '../reduxs/proto/action';

const { domain, apiPath, isMock } = config
export const REDUX_FETCH_TIMEOUT = 500
export const STRENGTH_LEVEL = {
  VERY_WEAK: { 
    name: '非常弱', 
    color: '#f5222d',
    className: 'very-weak'
  },
  WEAK: { 
    name: '弱', 
    color: '#ff7600',
    className: 'weak'
  },    
  AVERAGE: { 
    name: '一般', 
    color: '#ffab49',
    className: 'average'
  },  
  STRONG: { 
    name: '强', 
    color: '#40c1ff',
    className: 'strong'
  }, 
  VERY_STRONG: { 
    name: '非常强', 
    color: '#188fff',
    className: 'very-strong'
  },
  SECURE: { 
    name: '安全', 
    color: '#55d4c2',
    className: 'secure'
  },  
  VERY_SECURE: { 
    name: '非常安全', 
    color: '#52c41a',
    className: 'very-secure'
  }
}

var mockConf = null
const _HttpServices = new httpServices(domain, apiPath)

class mockServies {

  constructor (isMock = true) {
    this.isMock = isMock
    if (isMock) {
      mockConf = require('../../mock').default
    }
  }

  mock (url, params = {}, header = {}) {
    let mockData = null
    if (this.isMock) {
      mockData = mockConf && mockConf[urlFilter(url)]
    }
    let matcher = `${domain}${apiPath}${url.replace(/^(POST|GET)\:\s/, '')}`
    mockData && fetchMock.mock(matcher, mockData(params, header))
  }
  
  GET (url, params = {}, header = {}) {
    let mockData = null
    if (this.isMock) {
      mockData = mockConf && mockConf[`GET: ${urlFilter(url)}`]
    }
    let matcher = `${domain}${apiPath}${url}`
    mockData && fetchMock.mock(matcher, mockData(params, header))
    return _HttpServices.GET(url, params, header)
  }

  POST (url, params = {}, header = {}) {
    let mockData = null
    if (this.isMock) {
      mockData = mockConf && mockConf[`POST: ${urlFilter(url)}`]
    }
    let matcher = `${domain}${apiPath}${url}`
    let mockParams = params
    if (/\:id/.test(urlFilter(url))) {
      mockParams = {
        ...params,
        ...urlMatch(url)
      }
    }
    mockData && fetchMock.mock(matcher, mockData(mockParams, header))
    return _HttpServices.POST(url, params, header)
  }
}

export const HttpServices = new mockServies(isMock)

export const getReducers = (Reduxs) => {
  let Reducers = {}
  for (let e of _.keys(Reduxs)) {
    if (!/Reducer$/.test(e)) continue
    Reducers[_.upperFirst(e.replace(/Reducer$/, ''))] = Reduxs[e]
  }
  return Reducers
}

export const getRoutes = (Features) => {
  let Routes = []
  for (let e of _.keys(Features)) {
    Routes.push(Features[e])
  }
  return Routes
}

export const getMenuSub = (routes, opts) => {
  let menuSub = {
    name: routes.name,
    ...opts,
    data:  []
  }
  for (let e of routes.childRoutes) {
    !e.isIndex && menuSub.data.push({
      key: e.path,
      name: e.name,
      path: opts.key
    })
  }
  return menuSub
}

export const urlFilter = (url) => {
  return url.replace(/([a-f\d]+){24}/, ':id')
}

export const urlMatch = (url) => {
  let urlmatch = url.match(/([a-f\d]+){24}/)
  return urlmatch && { id: urlmatch[0] }
}

export const getDataSource = (data, opts = {}) => {
  let list = []
  let keyField = opts.key
  data && data.map((item, i) => {
    if (!_.has(item, 'key')) {
      item['key'] = keyField ? item[keyField] : i
    }
    list.push(item)
  })
  let dataSource = list
  if (opts.query) {
    dataSource = _.filter(dataSource, opts.query)
  }
  if (opts.order) {
    dataSource = _.orderBy(..._.concat([dataSource], opts.order))
  }
  return dataSource
}

export const getSiderMenus = (menuSubs, options) => {
  let siderMenus = {}
  if (!options) return menuSubs
  for (let e of _.keys(menuSubs)) {
    let menuSubItem = menuSubs[e]
    let menuSubOpts = _.find(options, { key: menuSubItem.key })
    if (!menuSubOpts) {
      siderMenus[e] = menuSubItem
      continue
    }
    if (menuSubOpts.open) {
      menuSubItem['data'] = getMenuSubItemData(menuSubItem, menuSubOpts)
      siderMenus[e] = menuSubItem
    }
  }
  return siderMenus
}

const getMenuSubItemData = (menuSubItem, menuSubOpts) => {
  let itemData = []
  if (!_.has(menuSubItem, 'data')) return itemData
  for (let e of menuSubItem.data) {
    let opts = _.has(menuSubOpts, 'children') 
      ? _.find(menuSubOpts.children, { key: e.key }) 
      : { open: true }
    _.has(opts, 'open') && opts.open && itemData.push(e)
  }
  return itemData
}

export const validRule = (rule, value) => {
  try {
    let pattern = rule.pattern || rule
    let reg = new RegExp(pattern)
    let valid = reg.test(value)
    let size = checkLength(value)
    if (rule.minlength && size < rule.minlength) {
      valid = false
    }
    if (rule.maxlength && size > rule.maxlength) {
      valid = false
    }
    return { valid, message: rule.message || '' }
  } catch (error) {
    console.log('Rules Error', error)
  }
}

const checkLength = (str) => {
  let size = 0
  if (_.isEmpty(str)) return size
  let arr = str.split('')
  for (let word of arr) {
    size++
    (/[^\x00-\xff]/g.test(word)) && size++
  }
  return size
}

export const getFlagValue = (auth, code, value = null, filter = true) => {
  if (!value || value.length < 2) {
    value = [true, false]
  }
  if (auth.group.level === 9999) {
    return value[1]
  }
  let back_value = value[1]
  if (auth.group.flag.indexOf(code) === -1) {
    back_value = value[0]
  }
  return !filter ? !back_value : back_value
}

export const showTeam = (team, teams) => {
  if (!team) {
    return '--'
  }
  let team_arr = []
  for (let item of team) {
    teams && team_arr.push(teams[item] || item)
  }
  return team_arr.length > 0 ? _.join(team_arr, ', ') : '--'
}

export const getTeamFlag = (team, auth) => {
  let concat = [...team, ...auth.group.team]
  let uniq = _.uniq(concat)
  return concat.length !== uniq.length
}

export const getPageFlag = (router, tag) => {
  let routerInfo = Flag[router]
  let info = _.find(routerInfo, o => o.key === tag)
  return info
}

export const strengthLevel = (strength) => {
  if (strength >= 90) {
    return STRENGTH_LEVEL.VERY_SECURE// '非常安全'
  }
  if (strength >= 80) {
    return STRENGTH_LEVEL.SECURE// '安全'
  }
  if (strength >= 70) {
    return STRENGTH_LEVEL.VERY_STRONG//'非常强'
  }
  if (strength >= 60) {
    return STRENGTH_LEVEL.STRONG// '强'
  }
  if (strength >= 50) {
    return STRENGTH_LEVEL.AVERAGE// '一般'
  }
  if (strength >= 25) {
    return STRENGTH_LEVEL.WEAK// '弱'
  }
  return STRENGTH_LEVEL.VERY_WEAK// '非常弱'
}

export const toDuration = (duration, format = null) => {
  let millisecond = duration % 1000
  let second = (duration - millisecond) / 1000
  let minute = 0
  let hour = 0
  let day = 0
  if (duration < 1000) {
    millisecond = duration
  }
  duration = second
  let duration_obj = { day, hour, minute, second, millisecond }
  if (duration < 3600) {
    second = duration % 60
    minute = (duration - second) / 60
  }
  if (duration < 3600 * 24) {
    second = duration % 60
    minute = (duration - second) / 60 % 60
    hour = (duration - duration % 3600) / 3600
  }
  if (duration >= 86400) {
    second = duration % 60
    minute = (duration - second) / 60 % 60
    hour = (duration - duration % 3600) / 3600 % 24
    day = (duration - duration % 86400) / 86400
  }
  if (format) {
    if (day > 0) {
      return _.template(format['day'])({ day, hour, minute, second, millisecond })
    }
    else if (hour > 0) {
      return _.template(format['hour'])({ hour, minute, second, millisecond })
    }
    else if (minute > 0) {
      return _.template(format['minute'])({ minute, second, millisecond })
    }
    else if (second > 0) {
      return _.template(format['second'])({ second, millisecond })
    }
    else {
      return _.template(format['millisecond'])({ millisecond })
    }
  }
  return { day, hour, minute, second, millisecond }
}

export const formatTime = (time) => {
  let out_arr = []
  let time_arr = time.split(':')
  for (let item of time_arr) {
    out_arr.push((Array(2).join(0) + Number(item)).slice(-2))
  }
  return out_arr.join(':')
}

export const getPostData = (postData, proto) => {
  let PostData = null
  let PostOptions = {}
  let BodyData = null
  if (_.has(postData, proto)) {
    PostData = postData[proto]
    PostOptions = PostData.opts
    BodyData = PostData.data
  }
  return { PostOptions, BodyData }
}

export const getFileBlob = (content, options = {}) => {
  let { type, encoding } = options
  return new Blob([content], {
    type: `${options.type || 'text/plain'};charset=${options.encoding || 'utf-8'}`,
  })
}

export const downloadBlod = (fileFlob, fileName) => {
  let link = document.getElementById('download-blob-file')
  if (!link) {
    link = document.createElement('a')
  }
  link.href = window.URL.createObjectURL(fileFlob)
  link.download = fileName || 'file'
  link.click()
}

export const showEmail = (email, start = 4) => {
  if (_.isEmpty(email)) {
    return ''
  }
  let name_str = email.replace(/([@][^@]+)$/, '')
  let suffix = email.match(/([@][^@]+)$/)
  let len = name_str.length - start
  let reg = new RegExp(`.(?!.*.{${len}})`, 'g')
  let new_name = name_str
  if (len > 1) {
    new_name = name_str.replace(reg, '*')
  }
  return `${new_name}${suffix[0]}`
}